package id.co.shuba.spamobile.task;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import id.co.shuba.spamobile.App;
import id.co.shuba.spamobile.Encryptor;
import id.co.shuba.spamobile.WSException;
import id.co.shuba.spamobile.data.DatabaseHandler;
import id.co.shuba.spamobile.data.MaintenanceVisitDB;
import id.co.shuba.spamobile.data.StandardDB;
import id.co.shuba.spamobile.model.UserInfo;
import id.co.shuba.spamobile.services.WebServiceHelper;
import id.co.shuba.spamobile.util.Base64;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.xmlpull.v1.XmlPullParserException;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class UploadMaintenanceVisitTask extends BaseProgressTask {
	WebServiceHelper _ws;
	DatabaseHandler _db;
	UserInfo _user;
	String _imei;
	INotify _notify;

	public UploadMaintenanceVisitTask(WebServiceHelper ws, DatabaseHandler db, INotify notify, UserInfo user, String imei) {
		_ws = ws;
		_db = db;
		_user = user;
		_imei = imei;
		_notify = notify;
	}	
	
	private JSONArray Upload(ArrayList<JSONObject> list) throws Exception {
		Encryptor enc = new Encryptor(
				Encryptor.ENC_AES,
				Encryptor.ENC_AES, App.createCompleteKey(_user.getEncryptionKey()), App.IV);
		String pwd = enc.decryptText(_user.getPassword());	
		
		Map<String, Object> properties = new HashMap<String, Object>();								
		JSONArray array = new JSONArray(list);								
		String data = Base64.encodeBytes(array.toString().getBytes(), Base64.GZIP);						
		properties.put("data", data);					
		properties.put("nip", _user.getNip());
		properties.put("password", pwd);
		properties.put("imei", _imei);
		properties.put("token", _user.getToken());
		
		String result = _ws.Call("UploadMaintenanceVisit", properties).toString();
		
		String strJSON = new String(Base64.decode(result, Base64.GZIP)); 			
		publishProgress(30);			
		
		JSONObject res = new JSONObject(strJSON);
		String error = res.getString("error");
		if (error.length() > 0 && !error.equals("null"))
			throw new WSException(error);
			
		JSONArray jsonArray = res.getJSONArray("result");	
		return jsonArray;
	}

	@Override
	protected AsyncTaskResult<Void> doInBackground(Object... params) {
		try {					
			publishStatus("Uploading...");						
			
			MaintenanceVisitDB mv = new MaintenanceVisitDB(_db);
			Cursor cursor = mv.getListExport(_user.getAoCode());
			ArrayList<JSONObject> list = new ArrayList<JSONObject>();		
			if (cursor.moveToFirst()) {
				int length = cursor.getCount();
				int step = (int)Math.ceil((double)(length/App.MAX_ROW_UPLOAD));
				
				int numStep = 1;				
				int i = 0;
				do {				
					JSONObject obj = new JSONObject();
					obj.put("id", cursor.getString(cursor.getColumnIndex("VISIT_ID")));
					obj.put("aoCode", cursor.getString(cursor.getColumnIndex("AO_CODE")));
					obj.put("unitCode", cursor.getString(cursor.getColumnIndex("UNIT_CODE")));
					obj.put("dateVisit", cursor.getString(cursor.getColumnIndex("DATE_VISIT")));
					obj.put("noAccount", cursor.getString(cursor.getColumnIndex("NO_ACCOUNT")));
					obj.put("debtorName", cursor.getString(cursor.getColumnIndex("DEBTOR_NAME")));
					obj.put("objectiveOfVisit", cursor.getString(cursor.getColumnIndex("OBJECTIVE_OF_VISIT")));
					obj.put("entryBy", cursor.getString(cursor.getColumnIndex("ENTRY_BY")));
					obj.put("entryDate", cursor.getString(cursor.getColumnIndex("ENTRY_DATE")));
					obj.put("updateBy", cursor.getString(cursor.getColumnIndex("UPDATE_BY")));
					obj.put("updateDate", cursor.getString(cursor.getColumnIndex("UPDATE_DATE")));
					obj.put("isDeleted", cursor.getString(cursor.getColumnIndex("IS_DELETED")));
					list.add(obj);
					i++;
					
					if (i == App.MAX_ROW_UPLOAD) {												
						UpdateStatus(list);				
						
						int progress = (int)(100 * ((float)numStep/length));						
						publishProgress(progress);						
												
						i = 0;
						numStep++;
						list.clear();						
					}						
				} while (cursor.moveToNext());
				
				if (numStep == step) {
					UpdateStatus(list);									
				}
			}
			cursor.close();						
			
			publishStatus("Done!");
			publishProgress(0);
			return new AsyncTaskResult<Void>((Void) null);
		} catch (WSException we) {
			publishStatus(we.getMessage());
			publishProgress(0);
			return new AsyncTaskResult<Void>(we);
		} catch (Exception e) {
			Log.e("Download", e.getMessage(), e);
			if (e.getMessage().contains("Unable to resolve") || e.getMessage().contains("failed to connect")) {
				publishStatus("Tidak dapat tersambung ke server");
			} else {
				publishStatus(e.getMessage());
			}
			publishProgress(0);
			return new AsyncTaskResult<Void>(e);
		}		
	}
	
	private void UpdateStatus(ArrayList<JSONObject> list) throws Exception {
		JSONArray jsonArray =  Upload(list);
		SQLiteDatabase sqlite = _db.getWritableDatabase();
		int arrayLength = jsonArray.length();						
		for (int z = 0; z < arrayLength; z++) {
			String successId = jsonArray.getString(z);
			MaintenanceVisitDB.updateUpload(sqlite, successId, _user.getNip());
		}	
	}

	@Override
	public String getTitle() {
		return "Maintenance Visit";
	}
	
	@Override
	protected void onPostExecute(AsyncTaskResult<Void> result) {		
		super.onPostExecute(result);
		
		_notify.notifyFinish(result.getError());
	}
}
